/**
 * 
 */
package com.hanhai.zrb.mobile.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.hanhai.common.annotation.LoginNeedless;
import com.hanhai.common.cache.Cache;
import com.hanhai.common.consts.GlobalConst;
import com.hanhai.common.enums.ErrorCode;
import com.hanhai.common.util.AES;
import com.hanhai.common.util.CommonUtil;
import com.hanhai.common.util.CookieWrapper;
import com.hanhai.common.util.MD5Util;
import com.hanhai.common.web.controller.BaseController;
import com.hanhai.zrb.api.biz.service.CityInfoService;
import com.hanhai.zrb.api.biz.service.UserBlacklistService;
import com.hanhai.zrb.api.biz.service.UserInfoService;
import com.hanhai.zrb.api.biz.service.UserRegisterService;
import com.hanhai.zrb.api.biz.service.UserService;
import com.hanhai.zrb.api.client.facade.UserStatisticDetailFacade;
import com.hanhai.zrb.api.client.result.LoginResult;
import com.hanhai.zrb.mobile.form.LoginForm;
import com.hanhai.zrb.mobile.result.BaseApiResult;
import com.hanhai.zrb.mobile.service.LoginUserService;
import com.hanhai.zrb.mobile.util.FrontLoginUtil;
import com.hanhai.zrb.model.common.BaseUser;
import com.hanhai.zrb.model.project.CityInfo;
import com.hanhai.zrb.model.user.User;
import com.hanhai.zrb.model.user.enums.GenderParam;
import com.hanhai.zrb.model.user.enums.UserInfoName;
import com.hanhai.zrb.model.user.vo.UserInfoVO;

/**
 * @author ricky
 *
 */
@LoginNeedless
@RestController
public class LoginApiController extends BaseController {

	private static final Logger logger = LoggerFactory.getLogger(LoginApiController.class);

	@Resource
	private CityInfoService cityInfoService;
	@Resource
	private UserService userService;
	
	@Resource
	private UserInfoService userInfoService;

	@Resource
	private LoginUserService loginUserService;

	//@Resource
	//private UserLoginFacade userLoginFacade;

	@Resource
	private UserRegisterService userRegisterService;
	
	@Resource
	private UserStatisticDetailFacade userStatisticDetailFacade;

	@Resource
	private Cache loginCache;

	@Value("#{configProperties['zhaorongbao.img.url']}")
	private String img_url;

	@Value("#{configProperties['zhaorongbao.domain']}")
	private String default_domain;
	@Resource
	private UserBlacklistService userBlacklistService;

	@RequestMapping("/dologin")
	public BaseApiResult doLogin(@Valid LoginForm loginForm, Errors errors,
			HttpServletRequest request, HttpServletResponse response) {
		String tip = "用户名或密码错误";
		BaseApiResult result = new BaseApiResult();
		result.setRes(0);
		if (errors.hasErrors()) {
			logger.info("user login error,param error");
			result.setMsg(tip);
			return result;
		}
		FrontLoginUtil.setCurrentUser(null);
		User user = loginUserService.findByLoginName(loginForm.getName());

		if (user == null) {
			logger.info("user login error,user not exist");
			result.setMsg(tip);
			return result;
		}
		List<Long> userIdListInBlacklist = userBlacklistService.listAllUserIdListNotExpired();
		boolean isBlack = userIdListInBlacklist.contains(user.getUid());
		if(isBlack){
			logger.error("Find a login request in blacklist,uid="+user.getUid());
			result.setMsg("黑名单用户，禁止登录，请联系APP客户");
			return result;
		}
		String checkPwd = MD5Util.sha1(loginForm.getPassword());
		boolean passwordRight = StringUtils
				.equals(user.getPassword(), checkPwd);
		if (passwordRight) {
			BaseUser baseUser = new BaseUser();
			baseUser.setUid(user.getUid());
			baseUser.setMobile(user.getUmobile());
			baseUser.setEmail(user.getUemail());
			baseUser.setName(user.getUname());
			baseUser.setPassword(user.getPassword());
			FrontLoginUtil.setCurrentUser(baseUser);

			try {
				
				String baseKey = getLoginTokenBaseKey(baseUser);
				
				findAndMarkOtherLoginByBaseKey(baseKey);
				
				String key = loginTokenAndCacheUser(baseUser, response,baseKey);
				
				Map<String, Object> data = buildApiUserInfo(user, key);
				Map<String, Object> statisticData = userStatisticDetailFacade.getStatisticMap(user.getUid());
				data.putAll(statisticData);
				result.setData(data);
				result.setRes(1);
				return result;
			} catch (Exception e) {
				logger.error("user login error ", e);
			}

		}

		result.setMsg(tip);
		return result;

	}
	
	private void findAndMarkOtherLoginByBaseKey(String baseKey){
		Set<String> keys = loginCache.getkeys(baseKey+"*");
		for(String key:keys){
			Object user = loginCache.getValue(key);
			if (user != null) {
				if (user instanceof BaseUser) {
					BaseUser baseUser = (BaseUser) user;
					baseUser.setLoginStatus(2);
					int timeout = FrontLoginUtil.timeout(baseUser.getAutoLogin());
					loginCache.add(key, baseUser, timeout);
				}
			}
		}
	}

	@RequestMapping("/dologinInfo")
	public BaseApiResult doLoginInfo(HttpServletRequest request,
			HttpServletResponse response) {
		BaseApiResult result = new BaseApiResult();
		BaseUser baseUser = FrontLoginUtil.getCurrentUser();
		if(baseUser==null){
			
			result.setMsg("会话超时，请重新登录");
			result.setRes(ErrorCode.NO_LOGIN.getCode());
		}
		User user = loginUserService.findByLoginName(baseUser.getMobile());
		try {
			//String key = loginTokenAndCacheUser(baseUser, response);
			Map<String, Object> data = buildApiForUserInfo(user);
			result.setData(data);
		} catch (Exception e) {
			logger.error("", e);
			result.setMsg("获取信息失败");
			result.setRes(0);

		}

		return result;
	}

	private Map<String, Object> buildApiForUserInfo(User user) {
		Map<String, Object> data = new HashMap<String, Object>();
		//data.put(GlobalConst.FrontCookieName, key);
		data.put("uid", user.getUid());
		data.put("uname", user.getUname());
		data.put("auth", user.getStatus() == 12 ? true : false);
		data.put("org", user.getOrg() == null ? "" : user.getOrg());
		data.put("orgId", user.getOrgId() == null ? "" : user.getOrgId()
				.toString());
		data.put("userType", user.getUid().toString().startsWith("200") ? "2"
				: "1");
		data.put("userTypeName",
				user.getUid().toString().startsWith("200") ? "政府" : "企业");
		data.put("uEmail", user.getUemail() == null ? "" : user.getUemail());
		data.put("uMobile", user.getUmobile());
		data.put("realname",
				user.getRealname() == null ? "" : user.getRealname());
		data.put("status", user.getStatus());
		data.put("statusName", user.getStatus() == 12 ? "已认证" : "未认证"); // 12:已认证
																		// 11:未认证
		data.put("idCard", user.getIdcard() == null ? "" : user.getIdcard());
		/*UserCenterResult huanxinImResult = userRegisterService
				.getHuanxinImInfo(user.getUid

				());
		if (huanxinImResult.isSuccess()) {
			for (Map.Entry<String, Object> entry : huanxinImResult
					.getHuanxinInfoMap

					().entrySet()) {
				data.put(entry.getKey(), entry.getValue());
			}
		}*/
		List<UserInfoName> queryEmunList = new ArrayList<UserInfoName>();
		queryEmunList.add(UserInfoName.GENDER);
		queryEmunList.add(UserInfoName.INFO);
		queryEmunList.add(UserInfoName.LOCATION);
		queryEmunList.add(UserInfoName.BIRTHDATE);
		queryEmunList.add(UserInfoName.IDCARD_PROVINCE);
		queryEmunList.add(UserInfoName.IDCARD_CITY);
		Map<String, String> map = findByNameEnumsForMap(user.getUid().toString

		(), queryEmunList);

		for (Map.Entry<String, String> entry : map.entrySet()) {
			data.put(entry.getKey(), entry.getValue());
		}

		return data;
	}

	private Map<String, Object> buildApiUserInfo(User user, String key) {
		Map<String, Object> data = new HashMap<String, Object>();
		data.put(GlobalConst.FrontCookieName, key);
		data.put("uid", user.getUid());
		data.put("uname", user.getRealname());
		data.put("realname", user.getRealname());
		data.put("uemail", user.getUemail());
		data.put("auth", user.getStatus() == 12 ? true : false);
		data.put("org", user.getOrg());
		data.put("orgId", user.getOrgId() == null ? "" : user.getOrgId()
				.toString());
		data.put("userType", user.getUid().toString().startsWith("200") ? "2"
				: "1");
		data.put("userTypeName",
				user.getUid().toString().startsWith("200") ? "政府" : "企业");
		//职务
		List<UserInfoName> queryNameList = new ArrayList<UserInfoName>();
		queryNameList.add(UserInfoName.POSITION);
		UserInfoVO userInfoVo = userInfoService.findByNameEnums(Long.toString(user.getUid()), queryNameList);
		Map<String, String> infoMap = userInfoVo.getInfoMap();
		String position = infoMap.get("POSITION");
		data.put("position", position);
		//行业
		data.put("industry", user.getIndustry());
		//行业id
		data.put("industryId", user.getIndustryId());
		String imgpath = user.getAvatar();
		if (StringUtils.isBlank(imgpath)) {
			imgpath = "";
		}
		data.put("avatar", imgpath);
		
		/*UserCenterResult result = userRegisterService.getHuanxinImInfo(user
				.getUid());
		if (result.isSuccess()) {
			data.putAll(result.getHuanxinInfoMap());
		}*/

		return data;
	}

	// 跨域
	/*
	 * @RequestMapping("/dologincross") public void doLoginCross(@Valid
	 * LoginForm loginForm, @RequestParam String
	 * 
	 * jsoncallback,Errors errors, HttpServletRequest request,
	 * HttpServletResponse response) { String tip = "用户名或密码不正确"; if
	 * (errors.hasErrors()) { super.jsonFailCross(response, tip,jsoncallback);
	 * return; } FrontLoginUtil.setCurrentUser(null); BaseUser user =
	 * loginUserService.findByLoginName(loginForm.getName());
	 * 
	 * if (user == null) { super.jsonFailCross(response, tip,jsoncallback);
	 * return; } String checkPwd = MD5Util.sha1(loginForm.getPassword());
	 * boolean passwordRight = StringUtils .equals(user.getPassword(),
	 * checkPwd); if (passwordRight) { FrontLoginUtil.setCurrentUser(user); }
	 * initAutoLogin(loginForm, user); if (user != null && passwordRight) { try
	 * { //loginLogAndCountBeforeCookie(request, user);
	 * loginCookieAndCacheUser(user, response);
	 * super.jsonSucceedCross(response,jsoncallback); return; } catch (Exception
	 * e) { e.printStackTrace(); } } super.jsonFailCross(response,
	 * tip,jsoncallback); return; }
	 */
	public void initAutoLogin(LoginForm loginForm, BaseUser user) {
		// 保持登录
		boolean autoLogin = false;
		if (loginForm.getAutoLogin() != null
				&& loginForm.getAutoLogin().equals(1)) {
			autoLogin = true;
		}
		user.setAutoLogin(autoLogin);
	}

	private String getLoginTokenBaseKey(BaseUser user)throws Exception {
		String key = AES.Encrypt(user.getUid() + "", GlobalConst.FRONT_AES_KEY);
		return key;
	}
	
	private String loginTokenAndCacheUser(BaseUser user,
			HttpServletResponse response,String baseKey) throws Exception {
		//String key = AES.Encrypt(user.getUid() + "", GlobalConst.FRONT_AES_KEY);
		// String p2pDomainName = p2pDomainName();
		String key = baseKey+RandomStringUtils.randomAlphabetic(6);
		
				
		String domain = this.default_domain;
		int expire = FrontLoginUtil.expire(user.getAutoLogin());
		int timeout = FrontLoginUtil.timeout(user.getAutoLogin());
		CookieWrapper.setCookie(response, GlobalConst.FrontCookieName, key,
				domain, expire);
		loginCache.add(key, user, timeout);
		return key;
	}

	private Map<String, String>  findByNameEnumsForMap(String id,List<UserInfoName> queryEmunList){
		Map<String, String> mapRet = new HashMap<String, String>();
		mapRet.put("GENDER",""); 
		mapRet.put("GENDERNAME",""); 
		mapRet.put("LOCATION",""); 
		mapRet.put("LOCATIONNAME",""); 
		mapRet.put("BIRTHDATE",""); 
		mapRet.put("IDCARD_PROVINCE",""); 
		mapRet.put("IDCARD_CITY",""); 
		UserInfoVO userInfoVO = new UserInfoVO();
		try {
			  userInfoVO = userInfoService.findByNameEnums(id, queryEmunList);
			  Map<String, String> map = userInfoVO.getInfoMap();
			  for (Map.Entry<String, String> entry : map.entrySet()) {
				  if("GENDER".equals(entry.getKey())){//性别:0-未知(UserAuthName),1-男(UserAuthName),2-女
						for(GenderParam status :GenderParam.values()){
							if((status.getCode().toString()).equals(entry.getValue())){
								mapRet.put("GENDERNAME",status.getValue());
							}
						}
					  mapRet.put("GENDER",entry.getValue()); 
				  }else if("LOCATION".equals(entry.getKey())){
					  //获取当前地区的中文字符和编码
					  try {
						CityInfo cityInfo = cityInfoService.selectByPostcode(entry.getValue());
						// District district = districtService.selectByCode(entry.getValue());
						if (null != cityInfo) {
							mapRet.put("LOCATIONNAME", cityInfo.getCityName());
						}
					} catch (Exception e) {
						// TODO: handle exception
						e.printStackTrace();
					}

					  
					  mapRet.put("LOCATION",entry.getValue());  
				  }else{
					  mapRet.put(entry.getKey(),entry.getValue());  
				  }
				  				  
			  }
		} catch (Exception e) {
			logger.error("",e);
		}

		
		return mapRet;
	}

	@RequestMapping("/doRefreshLogin")
	public BaseApiResult doRefreshLogin(Long uid, String password,
			HttpServletResponse response) {
		BaseApiResult result = new BaseApiResult();
		LoginResult loginResult = reLoginByUidAndPwd(uid,
				password,response);
		if (loginResult.isSuccess() == false) {
			result.setRes(0);
			result.setMsg(loginResult.getMsg());
			return result;
		}

		Map<String, Object> data = buildApiUserInfo(loginResult.getUser(), loginResult.getUt());

		result.setData(data);
		return result;

	}
	
	
	/**
	 * 重登陆，用户客户端保存用户id和密码，重新登陆用。
	 * 
	 * @param uid
	 * @param password
	 * @param response
	 * @return
	 */
	public LoginResult reLoginByUidAndPwd(Long uid,String password,HttpServletResponse response){
		LoginResult result = new LoginResult();
		String tip = "用户名或密码不正确";
		
		FrontLoginUtil.setCurrentUser(null);
		
		User user = userService.findById(uid);

		if (user == null) {
			result.setMsg(tip);
			return result;
		}
		String checkPwd = MD5Util.sha1(password);
		boolean passwordRight = StringUtils
				.equals(user.getPassword(), checkPwd);
		if (passwordRight) {
			BaseUser baseUser   = new BaseUser();
			baseUser.setUid(user.getUid());
			baseUser.setMobile(user.getUmobile());
			baseUser.setEmail(user.getUemail());
			baseUser.setName(user.getUname());
			baseUser.setPassword(user.getPassword());
			FrontLoginUtil.setCurrentUser(baseUser);
			try {
				
				String baseKey = getLoginTokenBaseKey(baseUser);
				
				findAndMarkOtherLoginByBaseKey(baseKey);
				
				String key = loginTokenAndCacheUser(baseUser, response,baseKey);
				
				//Map<String, Object> data = buildApiUserInfo(user, key);
				//String ut =loginCookieAndCacheUser(baseUser);
				result.setUt(key);
				result.setUser(user);
				result.setSuccess(true);
				return result;
			} catch (Exception e) {
				logger.error("",e);
			}
		}
		
		result.setMsg(tip);
		return result;
	}
	
	
}
